package com.example.wifiscan;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;


public class MainActivity extends Activity {


    WifiManager mainWifi;
    WifiReceiver receiverWifi;

    StringBuilder sb = new StringBuilder();

    private final Handler handler = new Handler();

    private ListView listAps;
    
    private List<String> aps;
    
    private ArrayAdapter<String> adapter;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        listAps = (ListView) findViewById(R.id.listAps);
        
        aps = new ArrayList<String>();
        
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,aps);
        
        listAps.setAdapter(adapter);
        
        mainWifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        
        Log.i("logs", "Inicio Tela");
        
        receiverWifi = new WifiReceiver();
        registerReceiver(receiverWifi, new IntentFilter(
                WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        if(mainWifi.isWifiEnabled()==false)
        {
            mainWifi.setWifiEnabled(true);
        }

        Log.i("logs", "Fim criação de tela "+mainWifi.isWifiEnabled());
        
//        final Button button = (Button) findViewById(R.id.button_id);
//        button.setOnClickListener(new View.OnClickListener() {
//            public void onClick(View v) {
//                // Perform action on click
//            }
//        });
        
        doInback();
    }

    public void doInback()
    {
        handler.postDelayed(new Runnable() {

            @Override
            public void run()
            {
                // TODO Auto-generated method stub
                mainWifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

                receiverWifi = new WifiReceiver();
                registerReceiver(receiverWifi, new IntentFilter(
                        WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
                mainWifi.startScan();
                doInback();
            }
        }, 1000);

    }

    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, 0, 0, "Refresh");
        menu.add(0, 1, 1, "Trilateração");
        return super.onCreateOptionsMenu(menu);
    }
    
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
    	switch(item.getItemId()){
    		case 0:
    			mainWifi.startScan();
    			return true;
    		
    		case 1:
    			Intent myIntent = new Intent(MainActivity.this, StartDraw.class);
    			//myIntent.putExtra("key", value); //Optional parameters
    			startActivity(myIntent);
    			return true;
    		default:
    			return super.onMenuItemSelected(featureId, item);}
    		
    	}
    	

        


    @Override
    protected void onPause()
    {
        unregisterReceiver(receiverWifi);
        super.onPause();
    }

    @Override
    protected void onResume()
    {
        registerReceiver(receiverWifi, new IntentFilter(
                WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        super.onResume();
    }

    public class WifiReceiver extends BroadcastReceiver
    {
        public void onReceive(Context c, Intent intent)
        {
        	
            ArrayList<String> connections=new ArrayList<String>();
            ArrayList<Float> Signal_Strenth= new ArrayList<Float>();

            sb = new StringBuilder();
            List<ScanResult> wifiList;
            wifiList = mainWifi.getScanResults();
            aps.clear();
            for(ScanResult s : wifiList)
            {
                connections.add(s.SSID);
                Log.i("logs", "ADD WIFI ID: "+s.SSID);
                DecimalFormat df = new DecimalFormat("#.##");
                Log.d("logs", s.BSSID + ": " + s.level + ", d: " + df.format(calculateDistance((double)s.level, s.frequency)) + "m");
                aps.add("MAC:"+s.BSSID+"-"+ s.SSID + ": " + s.level + "dbm, d1: " + df.format(calculateDistance((double)s.level, s.frequency)) + "m," +
                		"d2: " + df.format(calculateDistance2((double)s.level, s.frequency))+"m" +
                		", d3: " + df.format(calculateDistance3((double)s.level))
                		+ "m, Q: "+calculateQuality(s.level)+ "\n");
                
            }
            
            adapter.notifyDataSetChanged();

        }
        /**
         * http://en.wikipedia.org/wiki/Free-space_path_loss
         * 
         * 
         * @param levelInDb
         * @param freqInMHz
         * @return
         */
        public double calculateDistance(double levelInDb, double freqInMHz)    {
    	   double exp = (27.55 - (20 * Math.log10(freqInMHz)) + Math.abs(levelInDb)) / 20.0;
    	   return Math.pow(10.0, exp);
    	}
        /**
         * Unmanned Air Vehicle Based Localization and Range Estimation of Wi-Fi Nodes
         * 
         * @param levelInDb
         * @param freqInMHz
         * @return
         */
        public double calculateDistance2(double levelInDb, double freqInMHz)    {
     	   double exp = (-0.09 + 27.55 - (20 * Math.log10(freqInMHz)) + Math.abs(levelInDb)) / 20.0;
     	   return Math.pow(10.0, exp);
     	}
        
        /**
         * http://electronics.stackexchange.com/questions/83354/calculate-distance-from-rssi
         * http://www.ijitee.org/attachments/File/v2i2/A0359112112.pdf
         * http://www.s2is.org/Issues/v1/n2/papers/paper14.pdf
         * 
         * @param levelInDb
         * @return
         */
        public double calculateDistance3	(double levelInDb)    {
      	   double exp = (-40.00 - levelInDb) / 20.0;
      	   return Math.pow(10.0, exp);
      	}
        
        /**
         * http://electronics.stackexchange.com/questions/83354/calculate-distance-from-rssi
         * http://www.ijitee.org/attachments/File/v2i2/A0359112112.pdf
         * http://www.s2is.org/Issues/v1/n2/papers/paper14.pdf
         * 
         * @param levelInDb
         * @return
         */
        public double calculateDistance3N(double levelInDb)    {
        	
      	   double exp = (-40.00 - levelInDb) / 20.0;
      	   return Math.pow(10.0, exp);
      	}
        
        /**
         * http://stackoverflow.com/questions/15797920/how-to-convert-wifi-signal-strength-from-quality-percent-to-rssi-dbm
         * 
         * http://msdn.microsoft.com/en-us/library/windows/desktop/ms706828%28v=vs.85%29.aspx
         * 
         * @param dBm
         * @return
         */
        public String calculateQuality(double dBm){
        	double quality = 0.0;
        	
        	// dBm to Quality:
            if(dBm <= -100)
                quality = 0;
            else if(dBm >= -50)
                quality = 100;
            else
                quality = 2 * (dBm + 100);
            
            return quality+"%";
        }
    }



}